﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Linq;

namespace Gmantis.Controls.TileView
{
    public sealed class TileViewPanel : VirtualizingPanel
    {
        // Fields
        private DragHelper _dragHelper;
        private int _firstVisibleItemRank;
        private Dock CalculatedDock;
        private int ComputedColumns;
        private int ComputedRows;
        private bool dragHeader;
        private int Offset;
        private ScrollBar scrollBar;
        private TileView tileview;
        private TileViewItem tileviewItem;
        private int ViewportSize;

        // Methods
        public TileViewPanel()
        {
            EventHandler<DragStartedEventArgs> handler = null;
            EventHandler<DragCompletedEventArgs> handler2 = null;
            EventHandler<DragDeltaEventArgs> handler3 = null;
            ScrollEventHandler handler4 = null;
            this.scrollBar = new ScrollBar();
            if (this._dragHelper != null)
            {
                this._dragHelper.FinalizeDrag();
            }
            this._dragHelper = new DragHelper(this, DragHelperMode.Inertia | DragHelperMode.TranslateX | DragHelperMode.TranslateY, 1.0, false, false, false, false);
            if (handler == null)
            {
                handler = delegate(object s, DragStartedEventArgs e)
                {
                    this.tileview = this.GetItemsOwner();
                    if (this.tileview != null)
                    {
                        List<UIElement> list = this.UnderMouse(e).ToList<UIElement>();
                        foreach (UIElement element in list)
                        {
                            if (element is TileViewItem)
                            {
                                this.tileviewItem = element as TileViewItem;
                                break;
                            }
                        }
                        if (this.tileviewItem != null)
                        {
                            foreach (UIElement element2 in list)
                            {
                                if (this.tileviewItem._elementHeader == element2)
                                {
                                    this.dragHeader = true;
                                    break;
                                }
                            }
                            if (this.dragHeader)
                            {
                                int num = this.tileview.IndexFromTileViewItem(this.tileviewItem);
                                this.tileview.GrabbedIndex = num;
                            }
                        }
                    }
                };
            }
            this._dragHelper.DragStarted += handler;
            if (handler2 == null)
            {
                handler2 = delegate(object param0, DragCompletedEventArgs param1)
                {
                    if (this.dragHeader)
                    {
                        this.dragHeader = false;
                        this.tileview.GrabbedIndex = -1;
                    }
                };
            }
            this._dragHelper.DragCompleted += handler2;
            if (handler3 == null)
            {
                handler3 = delegate(object s, DragDeltaEventArgs e)
                {
                    if (((this.dragHeader && (this.tileview != null)) && this.tileview.CanUserReorder) && (this.tileviewItem.TileView != null))
                    {
                        int oldIndex = this.tileview.IndexFromTileViewItem(this.tileviewItem);
                        if (oldIndex != this.tileview.MaximizedIndex)
                        {
                            Point intersectingPoint = e.GetPosition(null);
                            IList listForUpdate = this.GetListForUpdate();
                            bool flag = false;
                            foreach (UIElement element in this.tileview.HitTestProjectionWorkaround(intersectingPoint))
                            {
                                if (element == this.tileview.Panel)
                                {
                                    flag = true;
                                    break;
                                }
                            }
                            if (flag)
                            {
                                Point position = e.GetPosition(this.tileview.Panel);
                                foreach (UIElement element2 in base.Children)
                                {
                                    TileViewItem item = element2 as TileViewItem;
                                    if (((item != null) && (item != this.tileviewItem)) && (item.LastFinalRect.HasValue && item.LastFinalRect.Value.Contains(position)))
                                    {
                                        int newIndex = this.tileview.IndexFromTileViewItem(item);
                                        if (newIndex != this.tileview.MaximizedIndex)
                                        {
                                            this.tileview.ShouldAnimate = true;
                                            if (listForUpdate == null)
                                            {
                                                this.tileview.Ranking.VirtualMove(oldIndex, newIndex);
                                                this.tileview.Panel.InvalidateMeasure();
                                            }
                                            else
                                            {
                                                object obj2 = this.tileview.Items[oldIndex];
                                                listForUpdate.RemoveAt(oldIndex);
                                                listForUpdate.Insert(newIndex, obj2);
                                                this.tileview.GrabbedIndex = newIndex;
                                                this.tileview.GrabbedLastRect = this.tileviewItem.LastFinalRect;
                                            }
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                };
            }
            this._dragHelper.DragDelta += handler3;
            this.scrollBar.SmallChange = 42.0;
            if (handler4 == null)
            {
                handler4 = delegate(object s, System.Windows.Controls.Primitives.ScrollEventArgs e)
                {
                    if (e.ScrollEventType == ScrollEventType.SmallDecrement)
                    {
                        TileView itemsOwner = this.GetItemsOwner();
                        if (((itemsOwner == null) || (itemsOwner.MaximizedItem != null)) || (itemsOwner.Columns <= 0))
                        {
                            this.SetOffset(this._firstVisibleItemRank - 1);
                        }
                        else if (this.CalculatedDock.GetOrientation() == Orientation.Horizontal)
                        {
                            this.SetOffset(this._firstVisibleItemRank - itemsOwner.Columns);
                        }
                        else
                        {
                            this.SetOffset(this._firstVisibleItemRank - itemsOwner.Rows);
                        }
                    }
                    else if (e.ScrollEventType == ScrollEventType.SmallIncrement)
                    {
                        TileView view2 = this.GetItemsOwner();
                        if (((view2 == null) || (view2.MaximizedItem != null)) || (view2.Columns <= 0))
                        {
                            this.SetOffset(this._firstVisibleItemRank + 1);
                        }
                        else if (this.CalculatedDock.GetOrientation() == Orientation.Horizontal)
                        {
                            this.SetOffset(this._firstVisibleItemRank + view2.Columns);
                        }
                        else
                        {
                            this.SetOffset(this._firstVisibleItemRank + view2.Rows);
                        }
                    }
                    else
                    {
                        this.SetOffset((int)e.NewValue);
                    }
                };
            }
            this.scrollBar.Scroll += handler4;
        }

        private static void Animate(TileView tileView, TileViewItem child, Rect rect)
        {
            if (child.LastFinalRect.HasValue && ((child.LastFinalRect != rect) && tileView.ShouldAnimate))
            {
                child.CacheMode = new BitmapCache();
                TransformGroup group = new TransformGroup();
                child.RenderTransform = group;
                ScaleTransform transform = new ScaleTransform();
                group.Children.Add(transform);
                transform.CenterX = 0.0;
                transform.CenterY = 0.0;
                TranslateTransform transform2 = new TranslateTransform();
                group.Children.Add(transform2);
                Duration animationDuration = tileView.AnimationDuration;
                Storyboard timeline = new Storyboard
                {
                    Duration = animationDuration
                };
                Storyboard.SetTarget(timeline, child);
                Storyboard storyboard2 = new Storyboard();
                timeline.Children.Add(storyboard2);
                Storyboard.SetTarget(storyboard2, child);
                storyboard2.Duration = animationDuration;
                DoubleAnimation element = new DoubleAnimation
                {
                    From = new double?(child.LastFinalRect.Value.X - rect.X)
                };
                Storyboard.SetTargetProperty(element, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[1].(TranslateTransform.X)", new object[0]));
                storyboard2.Children.Add(element);
                element.Duration = animationDuration;
                SetEasing(tileView, element);
                DoubleAnimation animation2 = new DoubleAnimation
                {
                    From = new double?(child.LastFinalRect.Value.Y - rect.Y)
                };
                Storyboard.SetTargetProperty(animation2, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[1].(TranslateTransform.Y)", new object[0]));
                storyboard2.Children.Add(animation2);
                animation2.Duration = animationDuration;
                SetEasing(tileView, animation2);
                Storyboard storyboard3 = new Storyboard();
                timeline.Children.Add(storyboard3);
                Storyboard.SetTarget(storyboard3, child);
                storyboard3.Duration = animationDuration;
                DoubleAnimation animation3 = new DoubleAnimation
                {
                    From = new double?((rect.Width == 0.0) ? 1.0 : (child.LastFinalRect.Value.Width / rect.Width)),
                    To = 1.0
                };
                Storyboard.SetTargetProperty(animation3, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)", new object[0]));
                storyboard3.Children.Add(animation3);
                animation3.Duration = animationDuration;
                SetEasing(tileView, animation3);
                DoubleAnimation animation4 = new DoubleAnimation
                {
                    From = new double?((rect.Height == 0.0) ? 1.0 : (child.LastFinalRect.Value.Height / rect.Height)),
                    To = 1.0
                };
                Storyboard.SetTargetProperty(animation4, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)", new object[0]));
                storyboard3.Children.Add(animation4);
                animation4.Duration = animationDuration;
                SetEasing(tileView, animation4);
                timeline.Begin();
            }
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            RectangleGeometry geometry = new RectangleGeometry
            {
                Rect = new Rect(new Point(), finalSize)
            };
            base.Clip = geometry;
            TileView itemsOwner = this.GetItemsOwner();
            Size size = new Size();
            for (int i = 0; i < base.Children.Count; i++)
            {
                UIElement element = base.Children[i];
                if (itemsOwner.IndexFromTileViewItem(element as TileViewItem) != itemsOwner.MaximizedIndex)
                {
                    if (size.Width < element.DesiredSize.Width)
                    {
                        size.Width = element.DesiredSize.Width;
                    }
                    if (size.Height < element.DesiredSize.Height)
                    {
                        size.Height = element.DesiredSize.Height;
                    }
                }
            }
            size.Width = Math.Min(finalSize.Width, Math.Ceiling(size.Width));
            size.Height = Math.Min(finalSize.Height, Math.Ceiling(size.Height));
            bool flag = (this.CalculatedDock == Dock.Left) || (this.CalculatedDock == Dock.Top);
            if (this.CalculatedDock.GetOrientation() == Orientation.Horizontal)
            {
                size.Width = Math.Ceiling(size.Width);
                this.scrollBar.Arrange(new Rect(flag ? size.Width : (finalSize.Width - this.scrollBar.DesiredSize.Width), 0.0, this.scrollBar.DesiredSize.Width, finalSize.Height));
            }
            else
            {
                size.Height = Math.Ceiling(size.Height);
                this.scrollBar.Arrange(new Rect(0.0, flag ? size.Height : (finalSize.Height - this.scrollBar.DesiredSize.Height), finalSize.Width, this.scrollBar.DesiredSize.Height));
            }
            for (int j = 1; j < base.Children.Count; j++)
            {
                Rect rect;
                TileViewItem item = (TileViewItem)base.Children[j];
                int index = itemsOwner.IndexFromTileViewItem(item);
                int num5 = itemsOwner.Ranking.RankFromIndex(index);
                if (itemsOwner.MaximizedItem == null)
                {
                    if (index == itemsOwner.GrabbedIndex)
                    {
                        Canvas.SetZIndex(item, 2);
                    }
                    else
                    {
                        item.ClearValue(Canvas.ZIndexProperty);
                    }
                    if (this.CalculatedDock.GetOrientation() == Orientation.Horizontal)
                    {
                        int num6 = (num5 - this._firstVisibleItemRank) / this.ComputedColumns;
                        int num7 = (num5 - this._firstVisibleItemRank) % this.ComputedColumns;
                        double x = Math.Floor((double)((num7 * (finalSize.Width - this.scrollBar.DesiredSize.Width)) / ((double)this.ComputedColumns)));
                        double num9 = Math.Floor((double)(((num7 + 1) * (finalSize.Width - this.scrollBar.DesiredSize.Width)) / ((double)this.ComputedColumns)));
                        double y = Math.Floor((double)((num6 * finalSize.Height) / ((double)this.ComputedRows)));
                        double num11 = Math.Floor((double)(((num6 + 1) * finalSize.Height) / ((double)this.ComputedRows)));
                        rect = new Rect(x, y, num9 - x, num11 - y);
                    }
                    else
                    {
                        int num12 = (num5 - this._firstVisibleItemRank) % this.ComputedRows;
                        int num13 = (num5 - this._firstVisibleItemRank) / this.ComputedRows;
                        double num14 = Math.Floor((double)((num13 * finalSize.Width) / ((double)this.ComputedColumns)));
                        double num15 = Math.Floor((double)(((num13 + 1) * finalSize.Width) / ((double)this.ComputedColumns)));
                        double num16 = Math.Floor((double)((num12 * (finalSize.Height - this.scrollBar.DesiredSize.Height)) / ((double)this.ComputedRows)));
                        double num17 = Math.Floor((double)(((num12 + 1) * (finalSize.Height - this.scrollBar.DesiredSize.Height)) / ((double)this.ComputedRows)));
                        rect = new Rect(num14, num16, num15 - num14, num17 - num16);
                    }
                }
                else if (index == itemsOwner.MaximizedIndex)
                {
                    Canvas.SetZIndex(item, 1);
                    if (this.CalculatedDock.GetOrientation() == Orientation.Horizontal)
                    {
                        rect = new Rect(flag ? (this.scrollBar.DesiredSize.Width + size.Width) : 0.0, 0.0, (finalSize.Width - this.scrollBar.DesiredSize.Width) - size.Width, finalSize.Height);
                    }
                    else
                    {
                        rect = new Rect(0.0, flag ? (this.scrollBar.DesiredSize.Height + size.Height) : 0.0, finalSize.Width, (finalSize.Height - this.scrollBar.DesiredSize.Height) - size.Height);
                    }
                }
                else
                {
                    if (index == itemsOwner.GrabbedIndex)
                    {
                        Canvas.SetZIndex(item, 2);
                    }
                    else
                    {
                        item.ClearValue(Canvas.ZIndexProperty);
                    }
                    if (this.CalculatedDock.GetOrientation() == Orientation.Horizontal)
                    {
                        rect = new Rect(flag ? 0.0 : ((finalSize.Width - this.scrollBar.DesiredSize.Width) - size.Width), item.Offset, size.Width, item.DesiredSize.Height);
                    }
                    else
                    {
                        rect = new Rect(item.Offset, flag ? 0.0 : ((finalSize.Height - this.scrollBar.DesiredSize.Height) - size.Height), item.DesiredSize.Width, size.Height);
                    }
                }
                Animate(itemsOwner, item, rect);
                item.LastFinalRect = new Rect?(rect);
                item.Arrange(rect);
            }
            itemsOwner.ShouldAnimate = false;
            return finalSize;
        }

        private TileViewItem Generate(int index)
        {
            TileViewItem item;
            GeneratorPosition position = base.ItemContainerGenerator.GeneratorPositionFromIndex(index);
            using (base.ItemContainerGenerator.StartAt(position, GeneratorDirection.Forward, true))
            {
                bool flag;
                item = (TileViewItem)base.ItemContainerGenerator.GenerateNext(out flag);
                if (flag || !base.Children.Contains(item))
                {
                    base.AddInternalChild(item);
                }
                if (!item.isPrepared)
                {
                    base.ItemContainerGenerator.PrepareItemContainer(item);
                }
            }
            return item;
        }

        private TileView GetItemsOwner()
        {
            return (TileView)ItemsControl.GetItemsOwner(this);
        }

        private IList GetListForUpdate()
        {
            IList itemsSource = null;
            if (!this.tileview.UpdateSourceCollection)
            {
                return null;
            }
            if (this.tileview.ItemsSource == null)
            {
                return this.tileview.Items;
            }
            itemsSource = this.tileview.ItemsSource as IList;
            if (itemsSource != null)
            {
                if (!(itemsSource is INotifyCollectionChanged))
                {
                    return null;
                }
                if (itemsSource.IsFixedSize)
                {
                    return null;
                }
                if (itemsSource.IsReadOnly)
                {
                    itemsSource = null;
                }
            }
            return itemsSource;
        }

        protected override Size MeasureOverride(Size availableSize)
        {
            Size size4;
            TileView itemsOwner = this.GetItemsOwner();
            itemsOwner.Panel = this;
            UIElementCollection children = base.Children;
            this.CalculatedDock = itemsOwner.MinimizedItemsPosition;
            Orientation orientation = this.CalculatedDock.GetOrientation();
            if (itemsOwner.MaximizedItem == null)
            {
                if (this.CalculatedDock == Dock.Left)
                {
                    this.CalculatedDock = Dock.Right;
                }
                else if (this.CalculatedDock == Dock.Top)
                {
                    this.CalculatedDock = Dock.Bottom;
                }
            }
            this.scrollBar.SetBinding(FrameworkElement.StyleProperty, new Binding().From<TileView>(itemsOwner, x => x.ScrollBarStyle));
            this.scrollBar.SetBinding(Control.BackgroundProperty, new Binding().From<TileView>(itemsOwner, x => x.Background));
            this.scrollBar.SetBinding(Control.ForegroundProperty, new Binding().From<TileView>(itemsOwner, x => x.Foreground));
            this.scrollBar.SetBinding(Control.BorderBrushProperty, new Binding().From<TileView>(itemsOwner, x => x.BorderBrush));
            this.scrollBar.SetBinding(ClearStyleExtensions.MouseOverBrushProperty, new Binding().From<TileView>(itemsOwner, x => x.MouseOverBrush));
            this.scrollBar.SetBinding(ClearStyleExtensions.PressedBrushProperty, new Binding().From<TileView>(itemsOwner, x => x.PressedBrush));
            if (base.Children.Count == 0)
            {
                base.AddInternalChild(this.scrollBar);
            }
            this.scrollBar.Orientation = this.CalculatedDock.GetOrientation().Opposite();
            bool flag = false;
            if (itemsOwner.ScrollBarVisibility == ScrollBarVisibility.Visible)
            {
                flag = true;
            }
            if ((itemsOwner.ScrollBarVisibility == ScrollBarVisibility.Auto) && (this.Offset > 0))
            {
                flag = true;
            }
            if (itemsOwner.Items.Count == 0)
            {
                if (itemsOwner.ScrollBarVisibility == ScrollBarVisibility.Auto)
                {
                    flag = false;
                }
                this._firstVisibleItemRank = 0;
            }
            else
            {
                this.ComputedColumns = itemsOwner.Columns;
                this.ComputedRows = itemsOwner.Rows;
                if ((this.ComputedRows <= 0) && (this.ComputedColumns <= 0))
                {
                    this.ComputedRows = (int)Math.Sqrt((double)itemsOwner.Items.Count);
                    this.ComputedColumns = this.ComputedRows;
                    if ((this.ComputedRows * this.ComputedColumns) < itemsOwner.Items.Count)
                    {
                        this.ComputedRows++;
                    }
                    if ((this.ComputedRows * this.ComputedColumns) < itemsOwner.Items.Count)
                    {
                        this.ComputedColumns++;
                    }
                }
                else if ((this.ComputedRows <= 0) && (0 < this.ComputedColumns))
                {
                    this.ComputedRows = (itemsOwner.Items.Count + (this.ComputedColumns - 1)) / this.ComputedColumns;
                }
                else if ((0 < this.ComputedRows) && (this.ComputedColumns <= 0))
                {
                    this.ComputedColumns = (itemsOwner.Items.Count + (this.ComputedRows - 1)) / this.ComputedRows;
                }
                this._firstVisibleItemRank = this.Offset;
                if (this._firstVisibleItemRank >= itemsOwner.Items.Count)
                {
                    this._firstVisibleItemRank = itemsOwner.Items.Count - 1;
                }
                if (itemsOwner.MaximizedItem == null)
                {
                    if (orientation == Orientation.Horizontal)
                    {
                        this._firstVisibleItemRank = (this._firstVisibleItemRank / this.ComputedColumns) * this.ComputedColumns;
                    }
                    else
                    {
                        this._firstVisibleItemRank = (this._firstVisibleItemRank / this.ComputedRows) * this.ComputedRows;
                    }
                }
            }
            Size size = new Size();
            Size size2 = new Size();
            double num = 0.0;
            int num2 = 0;
            if (itemsOwner.Items.Count == 0)
            {
                this.ViewportSize = 0;
            }
            else if (itemsOwner.MaximizedItem == null)
            {
                this.ViewportSize = this.ComputedRows * this.ComputedColumns;
                int num3 = itemsOwner.Items.Count - this._firstVisibleItemRank;
                if (orientation == Orientation.Horizontal)
                {
                    int num4 = (this.ViewportSize - num3) / this.ComputedColumns;
                    if (num4 > 0)
                    {
                        this._firstVisibleItemRank -= this.ComputedColumns * num4;
                    }
                }
                else
                {
                    int num5 = (this.ViewportSize - num3) / this.ComputedRows;
                    if (num5 > 0)
                    {
                        this._firstVisibleItemRank -= this.ComputedRows * num5;
                    }
                }
                if (this._firstVisibleItemRank < 0)
                {
                    this._firstVisibleItemRank = 0;
                }
                num2 = this._firstVisibleItemRank + this.ViewportSize;
                if (num2 >= itemsOwner.Items.Count)
                {
                    num2 = itemsOwner.Items.Count - 1;
                }
                for (int j = this._firstVisibleItemRank; j <= num2; j++)
                {
                    TileViewItem item = this.Generate(itemsOwner.Ranking.IndexFromRank(j));
                    if (orientation == Orientation.Horizontal)
                    {
                        item.Measure(new Size(Math.Floor((double)((availableSize.Width - this.scrollBar.DesiredSize.Width) / ((double)this.ComputedColumns))), Math.Floor((double)(availableSize.Height / ((double)this.ComputedRows)))));
                    }
                    else
                    {
                        item.Measure(new Size(Math.Floor((double)(availableSize.Width / ((double)this.ComputedColumns))), Math.Floor((double)((availableSize.Height - this.scrollBar.DesiredSize.Height) / ((double)this.ComputedRows)))));
                    }
                }
                if (itemsOwner.ScrollBarVisibility == ScrollBarVisibility.Auto)
                {
                    flag = itemsOwner.Items.Count > this.ViewportSize;
                }
                if (flag)
                {
                    this.scrollBar.Measure(availableSize);
                }
                else
                {
                    this.scrollBar.Measure(new Size());
                }
            }
            else
            {
                bool flag2 = false;
                int num7 = itemsOwner.Ranking.RankFromIndex(itemsOwner.MaximizedIndex);
                if ((num7 < this._firstVisibleItemRank) && (this._firstVisibleItemRank != (itemsOwner.Items.Count - 1)))
                {
                    this._firstVisibleItemRank++;
                }
                for (int k = this._firstVisibleItemRank; k < itemsOwner.Items.Count; k++)
                {
                    if (k == num7)
                    {
                        if (k == (itemsOwner.Items.Count - 1))
                        {
                            num2 = k - 1;
                            flag2 = true;
                        }
                    }
                    else
                    {
                        TileViewItem item2 = this.Generate(itemsOwner.Ranking.IndexFromRank(k));
                        item2.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
                        if (orientation == Orientation.Horizontal)
                        {
                            num += item2.DesiredSize.Height;
                        }
                        else
                        {
                            num += item2.DesiredSize.Width;
                        }
                        if (((orientation == Orientation.Horizontal) && (num > availableSize.Height)) || ((orientation == Orientation.Vertical) && (num > availableSize.Width)))
                        {
                            if (num2 == num7)
                            {
                                num2 = num7 - 1;
                            }
                            num2 = k - 1;
                            if (num2 < 0)
                            {
                                num2 = 0;
                            }
                            break;
                        }
                        if ((k == (itemsOwner.Items.Count - 1)) || ((num7 == (itemsOwner.Items.Count - 1)) && (k == (itemsOwner.Items.Count - 2))))
                        {
                            num2 = k;
                            flag2 = true;
                            break;
                        }
                    }
                }
                if (flag2)
                {
                    for (int n = this._firstVisibleItemRank - 1; n > -1; n--)
                    {
                        if (n != num7)
                        {
                            TileViewItem item3 = this.Generate(itemsOwner.Ranking.IndexFromRank(n));
                            item3.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
                            if (orientation == Orientation.Horizontal)
                            {
                                num += item3.DesiredSize.Height;
                            }
                            else
                            {
                                num += item3.DesiredSize.Width;
                            }
                            if (((this.CalculatedDock.GetOrientation() == Orientation.Horizontal) && (num > availableSize.Height)) || ((this.CalculatedDock.GetOrientation() == Orientation.Vertical) && (num > availableSize.Width)))
                            {
                                this._firstVisibleItemRank = n + 1;
                                if (num2 == num7)
                                {
                                    num2 = num7 + 1;
                                }
                                break;
                            }
                            if (n == 0)
                            {
                                this._firstVisibleItemRank = 0;
                                break;
                            }
                        }
                    }
                }
                double num10 = 0.0;
                for (int m = this._firstVisibleItemRank; m <= num2; m++)
                {
                    if (m != num7)
                    {
                        TileViewItem item4 = this.Generate(itemsOwner.Ranking.IndexFromRank(m));
                        item4.Offset = num10;
                        if (this.CalculatedDock.GetOrientation() == Orientation.Horizontal)
                        {
                            num10 += item4.DesiredSize.Height;
                        }
                        else
                        {
                            num10 += item4.DesiredSize.Width;
                        }
                        Size desiredSize = item4.DesiredSize;
                        if (size.Width < desiredSize.Width)
                        {
                            size.Width = desiredSize.Width;
                        }
                        if (size.Height < desiredSize.Height)
                        {
                            size.Height = desiredSize.Height;
                        }
                    }
                }
                if ((num7 >= this._firstVisibleItemRank) && (num7 <= num2))
                {
                    this.ViewportSize = num2 - this._firstVisibleItemRank;
                }
                else
                {
                    this.ViewportSize = (num2 - this._firstVisibleItemRank) + 1;
                }
                if (itemsOwner.ScrollBarVisibility == ScrollBarVisibility.Auto)
                {
                    flag = this.ViewportSize < (itemsOwner.Items.Count - 1);
                }
            }
            size.Width = Math.Min(availableSize.Width, Math.Ceiling(size.Width));
            size.Height = Math.Min(availableSize.Height, Math.Ceiling(size.Height));
            if (itemsOwner.MaximizedItem != null)
            {
                if (flag)
                {
                    if (orientation == Orientation.Horizontal)
                    {
                        this.scrollBar.Measure(new Size(availableSize.Width - size.Width, availableSize.Height));
                    }
                    else
                    {
                        this.scrollBar.Measure(new Size(availableSize.Width, availableSize.Height - size.Height));
                    }
                }
                else
                {
                    this.scrollBar.Measure(new Size());
                }
                TileViewItem item5 = this.Generate(itemsOwner.MaximizedIndex);
                if (orientation == Orientation.Horizontal)
                {
                    item5.Measure(new Size((availableSize.Width - size.Width) - this.scrollBar.DesiredSize.Width, availableSize.Height));
                }
                else
                {
                    item5.Measure(new Size(availableSize.Width, (availableSize.Height - size.Height) - this.scrollBar.DesiredSize.Height));
                }
                size2 = item5.DesiredSize;
            }
            for (int i = base.Children.Count - 1; i >= 0; i--)
            {
                UIElement element = base.Children[i];
                if (element != this.scrollBar)
                {
                    int index = itemsOwner.IndexFromTileViewItem((TileViewItem)element);
                    if (index != -1)
                    {
                        if (index == itemsOwner.MaximizedIndex)
                        {
                            continue;
                        }
                        int num14 = itemsOwner.Ranking.RankFromIndex(index);
                        if ((this._firstVisibleItemRank <= num14) && (num14 <= num2))
                        {
                            continue;
                        }
                        GeneratorPosition position = base.ItemContainerGenerator.GeneratorPositionFromIndex(index);
                        ((IRecyclingItemContainerGenerator)itemsOwner.ItemContainerGenerator).Recycle(position, 1);
                    }
                    this.RemoveInternalChildRange(i, 1);
                }
            }
            if (this.ComputedColumns == 0)
            {
                this.scrollBar.Maximum = 0.0;
            }
            else if (itemsOwner.MaximizedItem == null)
            {
                if (orientation == Orientation.Horizontal)
                {
                    int num15 = ((itemsOwner.Items.Count - 1) / this.ComputedColumns) + 1;
                    this.scrollBar.Maximum = (num15 * this.ComputedColumns) - this.ViewportSize;
                }
                else
                {
                    int num16 = ((itemsOwner.Items.Count - 1) / this.ComputedRows) + 1;
                    this.scrollBar.Maximum = (num16 * this.ComputedRows) - this.ViewportSize;
                }
            }
            else
            {
                this.scrollBar.Maximum = (itemsOwner.Items.Count - this.ViewportSize) - 1;
            }
            this.scrollBar.ViewportSize = this.ViewportSize;
            this.scrollBar.Value = this._firstVisibleItemRank;
            this.scrollBar.LargeChange = this.ViewportSize;
            if (itemsOwner.MaximizedItem == null)
            {
                size4 = new Size(size.Width * this.ComputedColumns, size.Height * this.ComputedRows);
            }
            else if (orientation == Orientation.Horizontal)
            {
                size4 = new Size(size2.Width + size.Width, Math.Min(availableSize.Height, Math.Max(num, size2.Height)));
            }
            else
            {
                double width = Math.Min(availableSize.Width, Math.Max(num, size2.Width));
                size4 = new Size(width, size2.Height + size.Height);
            }
            if (orientation == Orientation.Horizontal)
            {
                return new Size(this.scrollBar.DesiredSize.Width + size4.Width, Math.Max(this.scrollBar.DesiredSize.Height, size4.Height));
            }
            return new Size(Math.Max(this.scrollBar.DesiredSize.Width, size4.Width), this.scrollBar.DesiredSize.Height + size4.Height);
        }

        internal void RemoveInternalChildRange(int index, int range)
        {
            base.RemoveInternalChildRange(index, range);
        }

        private static void SetEasing(TileView tileView, DoubleAnimation animation)
        {
            animation.EasingFunction = tileView.AnimationEasingFunction;
        }

        private void SetOffset(int offset)
        {
            TileView itemsOwner = this.GetItemsOwner();
            if ((offset < 0) || (this.ViewportSize >= itemsOwner.Items.Count))
            {
                offset = 0;
            }
            else
            {
                int count = itemsOwner.Items.Count;
                int num2 = offset + this.ViewportSize;
            }
            this.Offset = offset;
            base.InvalidateMeasure();
        }

        private IEnumerable<UIElement> UnderMouse(DragEventArgs e)
        {
            UIElement relativeTo = null;
            TileView itemsOwner = this.GetItemsOwner();
            if (relativeTo == null)
            {
                DependencyObject obj2 = itemsOwner;
                for (DependencyObject obj3 = itemsOwner; obj3 != null; obj3 = VisualTreeHelper.GetParent(obj3))
                {
                    obj2 = obj3;
                }
                relativeTo = obj2 as UIElement;
            }
            Point position = e.GetPosition(relativeTo);
            UIElement iteratorVariable3 = itemsOwner.HitTestProjectionWorkaround(position).FirstOrDefault<UIElement>();
            if (iteratorVariable3 != null)
            {
                UIElement reference = iteratorVariable3;
                do
                {
                    yield return reference;
                    reference = VisualTreeHelper.GetParent(reference) as UIElement;
                }
                while (reference != null);
            }
        }
    }
}
